package aggregate

import (
	"context"
	"errors"
	"fmt"
	"sync"

	"gitee.com/leonscript/sally/v2/domain/entity"
	"gitee.com/leonscript/sally/v2/infrastructure"
	"gitee.com/leonscript/sally/v2/infrastructure/utils"

	"github.com/bytedance/sonic"
	"github.com/google/uuid"
	"gorm.io/gorm"
)

// TxContext 事务上下文，用于收集事务期间需要发布的事件
type TxContext struct {
	// events 收集的事件列表
	events []Event
	// mutex 保护events的并发安全
	mutex sync.Mutex
}

// AddEvent 向事务上下文中添加事件
// 该方法是线程安全的，可以在并发环境下使用
// 如果添加的是错误类型的事件，会清空所有已有的事件
//
// 参数说明:
//   - event: 需要添加的事件对象
func (tc *TxContext) AddEvent(event Event) {
	tc.mutex.Lock()
	defer tc.mutex.Unlock()

	// 如果是错误类型的事件，清空所有已有事件
	if event.IsErrorEvent() {
		tc.events = tc.events[:0]
	}

	tc.events = append(tc.events, event)
}

// GetEvents 获取事务上下文中收集的所有事件
// 该方法是线程安全的，返回事件列表的副本
//
// 返回值:
//   - []Event: 收集的事件列表副本
func (tc *TxContext) GetEvents() []Event {
	tc.mutex.Lock()
	defer tc.mutex.Unlock()
	// 返回副本以避免外部修改
	events := make([]Event, len(tc.events))
	copy(events, tc.events)
	return events
}

// Clear 清空事务上下文中的事件
// 该方法是线程安全的
func (tc *TxContext) Clear() {
	tc.mutex.Lock()
	defer tc.mutex.Unlock()
	tc.events = tc.events[:0]
}

type Clerk struct {
	Hook
	Reference
	EventService
	// beginTxFunc 开始事务的函数，用于依赖注入
	beginTxFunc func() (*gorm.DB, func(error) error)
	// nodeTemplateRepo 节点模板仓储接口，用于支持新的FindNextApprovalNode方法
	nodeTemplateRepo entity.NodeTemplateRepository
}

// SetBeginTxFunc 设置事务函数（用于测试）
func (s *Clerk) SetBeginTxFunc(fn func() (*gorm.DB, func(error) error)) {
	s.beginTxFunc = fn
}

// SetNodeTemplateRepository 设置节点模板仓储接口
// 用于支持新的FindNextApprovalNode方法，实现依赖注入
// 参数:
//
//	repo: 节点模板仓储接口实现
func (s *Clerk) SetNodeTemplateRepository(repo entity.NodeTemplateRepository) {
	s.nodeTemplateRepo = repo
}

// AddWorkflowTemplate 添加工作流模板配置
func (s *Clerk) AddWorkflowTemplate(ctx context.Context, workflowTemplateConfig WorkflowTemplateConfig) (workflowTemplateID string, nodeTemplateIDs []string, err error) {
	// 检查节点配置是否为空
	if len(workflowTemplateConfig.NodeTemplateConfigs) == 0 {
		return "", nil, errors.New("节点配置不能为空")
	}

	// 生成工作流模板ID
	uuidV7, err := uuid.NewV7()
	if err != nil {
		return "", nil, err
	}
	workflowTemplateID = uuidV7.String()

	// 启动事务
	tx, commitFunc := s.beginTx()
	defer func() {
		err = commitFunc(err)
	}()

	// 生成业务节点模板ID列表
	businessNodeTemplateIDs, err := s.generateNodeTemplateIDs(workflowTemplateConfig.NodeTemplateConfigs)
	if err != nil {
		return "", nil, err
	}

	// 生成开始节点ID
	startNodeUUID, err := uuid.NewV7()
	if err != nil {
		return "", nil, err
	}
	startNodeTemplateID := startNodeUUID.String()

	// 创建工作流模板，使用专门的开始节点
	workflowTemplate := entity.NewWorkflowTemplate(workflowTemplateID, workflowTemplateConfig.Name, startNodeTemplateID, workflowTemplateConfig.AutoApprovalConfig.Enable, entity.AutoApprovalStrategy(workflowTemplateConfig.AutoApprovalConfig.Strategy), workflowTemplateConfig.TimeoutAlertHours)
	if err = s.Reference.CreateWorkflowTemplateTX(ctx, workflowTemplate, tx); err != nil {
		return "", nil, err
	}

	// 查找开始节点类型的配置，确定第一个业务节点
	firstBusinessNodeID := s.findFirstBusinessNode(workflowTemplateConfig.NodeTemplateConfigs, businessNodeTemplateIDs)

	// 创建开始节点模板
	startNodeTemplate := entity.NewNodeTemplate(startNodeTemplateID, "开始", firstBusinessNodeID, entity.NodeTemplateKindStart, workflowTemplateID)
	// 设置空的业务参数为有效的JSON
	startNodeTemplate.BusinessParams = "{}"
	if err = s.Reference.CreateNodeTemplateTX(ctx, startNodeTemplate, tx); err != nil {
		return "", nil, err
	}

	// 创建业务节点模板和审批者配置
	if err = s.createNodeTemplatesAndReviewers(ctx, workflowTemplateID, workflowTemplateConfig.NodeTemplateConfigs, businessNodeTemplateIDs, tx); err != nil {
		return "", nil, err
	}

	// 返回所有节点ID（包括开始节点）
	nodeTemplateIDs = append([]string{startNodeTemplateID}, businessNodeTemplateIDs...)

	// 事务会在 defer 中通过 commitFunc 提交
	return workflowTemplateID, nodeTemplateIDs, nil
}

func (s *Clerk) StartWorkflow(ctx context.Context, req StartWorkFlowRequest) (err error) {
	// 查询工作流模板
	workflowTemplate, err := s.Reference.QueryWorkflowTemplateByID(ctx, req.WorkflowTemplateID)
	if err != nil {
		return err
	}

	// 校验工作流合法性
	if !workflowTemplate.IsValid() {
		return errors.New("workflow template is invalid")
	}

	// 启动支持事件收集的事务
	tx, txContext, commitFunc := s.beginTxWithEvents(ctx)
	defer func() {
		// 如果有错误，添加失败事件到事务上下文
		if err != nil {
			txContext.AddEvent(NewWorkflowStartFailedEvent(req.FormContent))
		}

		// 执行事务提交或回滚
		err = commitFunc(err)
	}()

	// 如果WorkflowID不为空，则表示启动的是草稿，需要先删除这个草稿
	if req.WorkflowID != "" {
		// 删除workflow
		if err = s.Reference.DeleteWorkflowByCondTX(ctx, req.WorkflowID, tx); err != nil {
			return err
		}
	}

	// 查找下一个审批节点
	conditionParams, err := entity.NewConditionParams(req.FormContent)
	if err != nil {
		return err
	}
	nextNodeTemplateID, err := s.Reference.FindNextApprovalNodeRecursive(
		ctx,
		workflowTemplate.StartNodeTemplateID,
		conditionParams,
		make(map[string]bool),
		0,
		10,
	)
	if err != nil {
		return err
	}

	// 如果没有下一个节点，说明是最后一个节点，直接审批通过
	if nextNodeTemplateID == "" {
		// 获取workflow实体（不需要创建node）
		workflow, err := s.getWorkflowFromStartWorkFlowRequest(ctx, req, "")
		if err != nil {
			return err
		}

		// 直接设置workflow为已通过状态
		workflow.Pass("系统自动审批：无需审批节点")

		// 创建已通过的workflow
		if err = s.Reference.CreateWorkflowTX(ctx, workflow, tx); err != nil {
			return err
		}

		// 收集工作流启动成功事件（事务提交后发布）
		txContext.AddEvent(NewWorkflowStartSuccessEvent(workflow.ID, req.FormContent))

		// 发布工作流通过事件
		txContext.AddEvent(NewWorkflowPassedEvent(workflow.ID, "", ""))

		return nil
	}

	// 创建node实体
	node := entity.NewUnderReviewNode(nextNodeTemplateID, "")

	// 获取workflow实体
	workflow, err := s.getWorkflowFromStartWorkFlowRequest(ctx, req, node.ID)
	if err != nil {
		return err
	}
	// 创建workflow
	if err = s.Reference.CreateWorkflowTX(ctx, workflow, tx); err != nil {
		return err
	}

	// 保存node
	node.WorkflowID = workflow.ID
	if err = s.Reference.CreateNodeTX(ctx, node, tx); err != nil {
		return err
	}

	// 获取审批任务
	nodeReviewerTasks, _, err := s.getTargetNodeReviewerTasks(ctx, node.NodeTemplateID, node.ID, workflow)
	if err != nil {
		return err
	}
	if len(nodeReviewerTasks) == 0 {
		return nil
	}

	// 创建审批任务
	if err = s.Reference.CreateReviewerTasksTX(ctx, nodeReviewerTasks, tx); err != nil {
		return err
	}

	// 收集审批任务创建事件（事务提交后发布）
	txContext.AddEvent(NewReviewTasksCreatedEvent(workflow.ID, node.ID, ""))

	// 自动审批
	if err = s.autoPassReviewerTaskWithEvents(ctx, req.SponsorID, nodeReviewerTasks, tx, txContext); err != nil {
		return err
	}

	// 收集工作流启动成功事件（事务提交后发布）
	txContext.AddEvent(NewWorkflowStartSuccessEvent(workflow.ID, req.FormContent))

	// 事务会在 defer 中通过 commitFunc 提交，事件会在提交成功后发布
	return nil
}

// RestartWorkflow 重启审批流
func (s *Clerk) RestartWorkflow(ctx context.Context, req RestartWorkFlowRequest) (err error) {
	// 查询workflow信息
	workflow, err := s.Reference.QueryWorkflowByID(ctx, req.WorkflowID)
	if err != nil {
		return err
	}

	// 启动事务
	tx, commitFunc := s.beginTx()
	defer func() {
		err = commitFunc(err)
	}()

	// 归档当前workflow
	workflow.Archive()
	if err = s.Reference.UpdateWorkflowTX(ctx, workflow, tx); err != nil {
		return err
	}

	// 查询workflow的template
	workflowTemplate, err := s.Reference.QueryWorkflowTemplateByID(ctx, workflow.WorkflowTemplateID)
	if err != nil {
		return err
	}

	// 构建StartWorkflow的请求体
	var startWorkFlowRequest StartWorkFlowRequest
	if err = utils.StructCopy(ctx, &startWorkFlowRequest, &req); err != nil {
		return err
	}
	startWorkFlowRequest.WorkflowID = ""
	startWorkFlowRequest.WorkflowTemplateID = workflowTemplate.ID
	startWorkFlowRequest.Conclusion = workflow.Conclusion

	// 调用StartWorkflow
	if err = s.StartWorkflow(ctx, startWorkFlowRequest); err != nil {
		return err
	}

	// 事务会在 defer 中通过 commitFunc 提交
	return nil
}

func (s *Clerk) UpdateWorkflowContent(ctx context.Context, workflowID, formContent string, businessParams BusinessParams) (err error) {
	// 查询workflow信息
	workflow, err := s.Reference.QueryWorkflowByID(ctx, workflowID)
	if err != nil {
		return err
	}

	// 校验
	if !workflow.IsValidToUpdateContent() {
		return errors.New("当前工作流状态不支持修改内容")
	}

	// 更新工作流
	workflow.SetFormContent(formContent)
	params, err := businessParams.Marshal()
	if err != nil {
		return errors.New("自定义参数序列化失败")
	}
	workflow.SetBusinessParams(params)
	if err = s.Reference.UpdateWorkflow(ctx, workflow); err != nil {
		return err
	}

	return err
}

func (s *Clerk) RemoveWorkflow(ctx context.Context, workflowID string) (err error) {
	// 启动支持事件的事务
	tx, txCtx, commitFunc := s.beginTxWithEvents(ctx)
	defer func() {
		err = commitFunc(err)
	}()

	// 添加工作流删除事件（在实际删除之前发布）
	deleteEvent := NewWorkflowDeletedEvent(workflowID)
	txCtx.AddEvent(deleteEvent)

	// 删除task
	if err = s.Reference.DeleteNodeReviewerTaskByCondTX(ctx, workflowID, tx); err != nil {
		return err
	}
	// 删除node
	if err = s.Reference.DeleteNodeByCondTX(ctx, workflowID, tx); err != nil {
		return err
	}
	// 删除workflow
	if err = s.Reference.DeleteWorkflowByCondTX(ctx, workflowID, tx); err != nil {
		return err
	}

	// 事务会在 defer 中通过 commitFunc 提交
	return nil
}

// SaveWorkflowDraft 暂存工作流草稿
// 只创建工作流实体并存储到数据库中，不会创建节点和任务
func (s *Clerk) SaveWorkflowDraft(ctx context.Context, req StartWorkFlowRequest) (err error) {
	// 校验工作流合法性
	workflowTemplate, err := s.Reference.QueryWorkflowTemplateByID(ctx, req.WorkflowTemplateID)
	if err != nil {
		return err
	}

	if !workflowTemplate.IsValid() {
		return errors.New("workflow template is invalid")
	}

	// 启动事务
	tx, commitFunc := s.beginTx()
	defer func() {
		err = commitFunc(err)
	}()

	// 创建workflow草稿类型的实体
	workflow, err := s.getWorkflowFromStartWorkFlowRequest(ctx, req, "")
	if err != nil {
		return err
	}
	workflow.SetDraft()

	// 执行workflow的更新或者创建
	if req.WorkflowID == "" {
		if err = s.Reference.CreateWorkflowTX(ctx, workflow, tx); err != nil {
			return err
		}
	} else {
		if err = s.Reference.UpdateWorkflowTX(ctx, workflow, tx); err != nil {
			return err
		}
	}

	// 事务会在 defer 中通过 commitFunc 提交
	return nil
}

// Review 审批方法，支持多种审批策略
func (s *Clerk) Review(ctx context.Context, req ReviewRequest) (err error) {
	// 查询任务信息
	nodeReviewerTask, err := s.Reference.QueryReviewerTaskByID(ctx, req.NodeReviewerTaskID)
	if err != nil {
		return err
	}
	// 校验任务状态
	if !nodeReviewerTask.IsValidToReview() {
		return errors.New("任务已经被审批")
	}
	// 赋予任务评论
	nodeReviewerTask.Comment, err = req.Comment.Marshal()
	if err != nil {
		return err
	}

	// 启动事务
	tx, txCtx, commitFunc := s.beginTxWithEvents(ctx)
	defer func() {
		err = commitFunc(err)
	}()
	// 通过任务id查询审批流信息，并上锁
	workflow, err := s.Reference.QueryAndLockWorkflowByCondTX(ctx, QueryWorkflowCond{
		ReviewerTaskID: req.NodeReviewerTaskID,
	}, tx)
	if err != nil {
		return fmt.Errorf("查询workflow信息失败: %v", err)
	}

	// 校验审批流状态
	if !workflow.IsValidToReview(nodeReviewerTask.NodeID) {
		return errors.New("审批流已经被审批")
	}

	// 更新当前任务状态
	if req.IsPass() {
		nodeReviewerTask.Pass()
	} else {
		nodeReviewerTask.Reject()
	}
	if err = s.Reference.UpdateNodeReviewerTaskTX(ctx, nodeReviewerTask, tx); err != nil {
		return err
	}

	// 创建审批决策器
	decisionMaker := NewApprovalDecisionMaker(s.Reference)

	// 做出节点审批决策
	nodeApprovalDecision, err := decisionMaker.MakeNodeApprovalDecision(ctx, nodeReviewerTask, req.IsPass(), tx)
	if err != nil {
		return err
	}

	// 处理节点级别的操作
	// 如果触发了节点的审批通过/驳回
	if !nodeApprovalDecision.ApprovalResult.ShouldContinue {
		// 执行节点处理逻辑
		if nodeApprovalDecision.ApprovalResult.ShouldPass {
			// 节点通过
			err = s.passNodeHandlerWithEvents(ctx, workflow, nodeApprovalDecision.Node, nodeReviewerTask, tx, txCtx)
		} else {
			err = s.rejectNodeHandlerWithEvents(ctx, workflow, nodeApprovalDecision.Node, nodeReviewerTask, tx, txCtx)
		}
		if err != nil {
			return err
		}

		// 归档该节点的其他未被审批的任务
		if err = s.archiveOtherTasksOfNode(ctx, nodeReviewerTask.NodeID, tx); err != nil {
			return err
		}
	}
	// ShouldContinue 情况下不需要额外操作，继续等待其他审批

	// 事务会在 defer 中通过 commitFunc 提交
	// 注意：如果是外部传入的事务(req.tx != nil)，则不会在这里提交
	return nil
}

// CancelWorkflow 撤销工作流
// 该方法会把工作流、工作流当前的节点和还未审批的任务的状态都设置为已撤销
func (s *Clerk) CancelWorkflow(ctx context.Context, workflowID string) (err error) {
	// 查询workflow信息并上锁、修改状态为撤销
	// 通过workflowID查询节点和审批任务，修改这些元素的状态为撤销

	// 锁定工作流
	workflow, err := s.Reference.QueryWorkflowByID(ctx, workflowID)
	if err != nil {
		return err
	}

	tx, txCtx, commitFunc := s.beginTxWithEvents(ctx)
	defer func() {
		err = commitFunc(err)
	}()
	workflow, err = s.Reference.QueryAndLockWorkflowByCondTX(ctx, QueryWorkflowCond{
		WorkflowID: workflowID,
	}, tx)
	if err != nil {
		return fmt.Errorf("锁定工作流失败: %v", err)
	}

	// 修改workflow状态为已撤销
	workflow.Cancel()
	if err = s.Reference.UpdateWorkflowTX(ctx, workflow, tx); err != nil {
		return err
	}

	// 修改当前节点状态为已撤销
	node, err := s.Reference.QueryNodeByIDTX(ctx, workflow.CurrentNodeID, tx)
	if err != nil {
		return err
	}
	node.Cancel()
	if err = s.Reference.UpdateNodeTX(ctx, node, tx); err != nil {
		return err
	}

	// 修改所有未完成的任务状态为已撤销
	cond := entity.NodeReviewerTask{NodeID: workflow.CurrentNodeID, Status: entity.TaskUnderReviewStatus}
	nodeReviewerTask := entity.NodeReviewerTask{Status: entity.TaskCanceledStatus}
	if err = s.Reference.UpdateNodeReviewerTaskByCondTX(ctx, cond, nodeReviewerTask, tx); err != nil {
		return err
	}

	// 添加工作流撤销事件
	cancelEvent := NewWorkflowCanceledEvent(workflowID)
	txCtx.AddEvent(cancelEvent)

	// 事务会在 defer 中通过 commitFunc 提交
	return nil
}

func (s *Clerk) GetWorkflows(ctx context.Context, req GetWorkflowsRequest) (result []ActivatedWorkflow, total int64, err error) {
	// 查询workflow列表
	result, total, err = s.Reference.QueryActivatedWorkflows(ctx, req)
	if err != nil {
		return result, total, err
	}

	// 收集所有当前节点ID
	var currentNodeIDs []string
	for _, workflow := range result {
		if workflow.CurrentNodeID != "" {
			currentNodeIDs = append(currentNodeIDs, workflow.CurrentNodeID)
		}
	}

	// 如果没有当前节点，直接返回
	if len(currentNodeIDs) == 0 {
		return result, total, nil
	}

	// 批量查询所有当前节点的审批任务
	allReviewTasks, _, err := s.Reference.QueryNodeReviewTasks(ctx, GetNodeReviewTasksRequest{
		PageCond: PageCond{NoPage: true},
		NodeIDs:  currentNodeIDs, // 使用节点ID列表进行批量查询
	})
	if err != nil {
		// 如果批量查询失败，返回原始结果（不包含审批人信息）
		return result, total, nil
	}

	// 构建节点ID到审批人ID列表的映射
	nodeReviewerMap := make(map[string][]string)
	for _, task := range allReviewTasks {
		nodeReviewerMap[task.NodeID] = append(nodeReviewerMap[task.NodeID], task.ReviewerID)
	}

	// 为每个工作流补充审批人ID信息
	for i := range result {
		if reviewerIDs, exists := nodeReviewerMap[result[i].CurrentNodeID]; exists {
			result[i].CurrentNodeReviewerIDs = reviewerIDs
		}
	}

	return result, total, nil
}

func (s *Clerk) GetNodeReviewTasks(ctx context.Context, req GetNodeReviewTasksRequest) (result []NodeReviewTask, total int64, err error) {
	// 查询审批任务列表
	return s.Reference.QueryNodeReviewTasks(ctx, req)
}

func (s *Clerk) GetWorkflow(ctx context.Context, workflowID string) (result ActivatedWorkflow, err error) {
	// 查询workflow信息
	workflow, err := s.Reference.QueryWorkflowByID(ctx, workflowID)
	if err != nil {
		return result, err
	}

	// 查询workflow模板信息
	workflowTemplate, err := s.Reference.QueryWorkflowTemplateByID(ctx, workflow.WorkflowTemplateID)
	if err != nil {
		return result, err
	}

	// 转换为ActivatedWorkflow类型
	result = ActivatedWorkflow{
		ID:            workflow.ID,
		FormContent:   workflow.FormContent,
		Name:          workflowTemplate.Name,
		BusinessID:    workflow.BusinessID,
		BusinessCode:  workflow.BusinessCode,
		CurrentNodeID: workflow.CurrentNodeID,
		Status:        workflow.Status,
		Conclusion:    workflow.Conclusion,
		SponsorID:     workflow.SponsorID,
		CreatedAt:     workflow.CreatedAt,
		UpdatedAt:     workflow.UpdatedAt,
	}

	// 转换BusinessParams
	result.BusinessParams, err = NewBusinessParams(workflow.BusinessParams)
	if err != nil {
		return result, err
	}

	// 查询workflow当前节点的审批任务
	result.CurrentNodeReviewTasks, _, err = s.Reference.QueryNodeReviewTasks(ctx, GetNodeReviewTasksRequest{
		PageCond: PageCond{
			NoPage: true,
		},
		NodeID: result.CurrentNodeID,
	})
	if err != nil {
		return result, err
	}

	return result, err
}

// GetNode 根据ID获取节点详情
func (s *Clerk) GetNode(ctx context.Context, nodeID string) (result ActivatedNode, err error) {
	// 启动事务
	tx, commitFunc := s.beginTx()
	defer func() {
		err = commitFunc(err)
	}()

	// 查询节点信息
	node, err := s.Reference.QueryNodeByIDTX(ctx, nodeID, tx)
	if err != nil {
		return result, err
	}

	// 查询节点模板信息
	nodeTemplate, err := s.Reference.QueryNodeTemplateByID(ctx, node.NodeTemplateID)
	if err != nil {
		return result, err
	}

	// 转换为ActivatedNode类型
	result = ActivatedNode{
		ID:             node.ID,
		WorkflowID:     node.WorkflowID,
		NodeTemplateID: node.NodeTemplateID,
		Status:         node.Status,
		CreatedAt:      node.CreatedAt,
		UpdatedAt:      node.UpdatedAt,
		// 节点模板信息
		NodeTemplateName:   nodeTemplate.Name,
		NodeTemplateKind:   nodeTemplate.Kind,
		ApprovalStrategy:   string(nodeTemplate.ApprovalStrategy),
		NextNodeTemplateID: nodeTemplate.NextNodeTemplateID,
	}

	// 转换BusinessParams
	if nodeTemplate.BusinessParams != "" {
		result.NodeTemplateBusinessParams, err = NewBusinessParams(nodeTemplate.BusinessParams)
		if err != nil {
			return result, err
		}
	} else {
		result.NodeTemplateBusinessParams = make(BusinessParams)
	}

	// 查询节点的审批任务
	result.NodeReviewTasks, _, err = s.Reference.QueryNodeReviewTasks(ctx, GetNodeReviewTasksRequest{
		PageCond: PageCond{
			NoPage: true,
		},
		NodeID: nodeID,
	})
	if err != nil {
		return result, err
	}

	return result, nil
}

// GetWorkflowProgress 根据工作流ID查询整个工作流进度
// 简化版本：只查询当前有未完成审批任务的节点，避免复杂的条件节点处理逻辑
//
// 参数说明:
//   - ctx: 上下文对象，用于控制请求生命周期
//   - workflowID: 工作流ID
//
// 返回值:
//   - result: 工作流进度信息，包含基本信息和当前活跃节点的进度
//   - err: 查询过程中可能出现的错误
//
// 功能说明:
//  1. 查询工作流基本信息和模板信息
//  2. 查询当前有未完成审批任务的节点
//  3. 构建简化的节点进度信息，包含节点名称
func (s *Clerk) GetWorkflowProgress(ctx context.Context, workflowID string) (result WorkflowProgress, err error) {
	// 实现步骤：
	// 1. 查询工作流基本信息和模板信息
	// 2. 查询当前有未完成审批任务的节点
	// 3. 构建节点进度信息，确保包含节点名称

	// 1. 查询工作流基本信息
	workflow, err := s.Reference.QueryWorkflowByID(ctx, workflowID)
	if err != nil {
		return result, err
	}

	// 2. 查询工作流模板信息
	workflowTemplate, err := s.Reference.QueryWorkflowTemplateByID(ctx, workflow.WorkflowTemplateID)
	if err != nil {
		return result, err
	}

	// 3. 构建工作流基本进度信息
	result = WorkflowProgress{
		WorkflowID:   workflow.ID,
		WorkflowName: workflowTemplate.Name,
		Status:       workflow.Status,
		SponsorID:    workflow.SponsorID,
		FormContent:  workflow.FormContent,
	}

	// 转换BusinessParams
	result.BusinessParams, err = NewBusinessParams(workflow.BusinessParams)
	if err != nil {
		return result, err
	}

	// 4. 查询已经处理和正在处理的节点信息
	nodeProgresses, err := s.buildActiveNodeProgresses(ctx, workflowID)
	if err != nil {
		return result, err
	}

	result.NodeProgresses = nodeProgresses

	return result, nil
}

// buildActiveNodeProgresses 构建从第一个审批节点到当前审批节点的进度信息
// 简化版本：从工作流的第一个审批节点开始，按顺序查询到当前还在审批中的节点
//
// 参数说明:
//   - ctx: 上下文对象，用于控制请求生命周期
//   - workflowID: 工作流ID
//
// 返回值:
//   - []NodeProgress: 从第一个审批节点到当前审批节点的进度信息列表，包含节点名称
//   - error: 查询过程中可能出现的错误
//
// 功能说明:
//  1. 查询工作流模板，获取第一个审批节点
//  2. 查询工作流中所有已创建的节点
//  3. 按照节点模板链顺序，从第一个审批节点开始遍历到当前审批节点
//  4. 构建包含节点名称的进度信息
//
// buildActiveNodeProgresses 构建工作流的活跃节点进度信息
// 从第一个审批节点开始，按顺序查询到当前卡在审批中的节点
// 参数：
//   - ctx: 上下文
//   - workflowID: 工作流ID
//
// 返回值：
//   - []NodeProgress: 节点进度列表
//   - error: 错误信息
func (s *Clerk) buildActiveNodeProgresses(ctx context.Context, workflowID string) ([]NodeProgress, error) {
	// 实现步骤：
	// 1. 查询工作流基本信息
	// 2. 查询已创建的节点（按创建时间排序）
	// 3. 查询审批任务并构建进度信息
	// 4. 遇到未完成的审批任务时停止

	// 1. 查询工作流信息
	workflow, err := s.Reference.QueryWorkflowByID(ctx, workflowID)
	if err != nil {
		return nil, err
	}

	// 2. 查询工作流中所有已创建的节点（按创建时间排序）
	nodes, err := s.Reference.QueryNodesByWorkflowID(ctx, workflowID)
	if err != nil {
		return nil, err
	}

	if len(nodes) == 0 {
		return []NodeProgress{}, nil
	}

	// 3. 查询所有审批任务
	allReviewTasks, _, err := s.Reference.QueryNodeReviewTasks(ctx, GetNodeReviewTasksRequest{
		PageCond:   PageCond{NoPage: true},
		WorkflowID: workflowID,
	})
	if err != nil {
		return nil, err
	}

	// 4. 查询节点模板信息
	nodeTemplates, err := s.Reference.QueryNodeTemplatesByWorkflowTemplateID(ctx, workflow.WorkflowTemplateID)
	if err != nil {
		return nil, err
	}

	// 5. 构建映射表
	nodeTemplateMap := make(map[string]entity.NodeTemplate, len(nodeTemplates))
	for _, template := range nodeTemplates {
		nodeTemplateMap[template.ID] = template
	}

	reviewTaskMap := make(map[string][]NodeReviewTask)
	for _, task := range allReviewTasks {
		reviewTaskMap[task.NodeID] = append(reviewTaskMap[task.NodeID], task)
	}

	// 6. 按节点创建顺序构建进度信息
	nodeProgresses := make([]NodeProgress, 0, len(nodes))
	for _, node := range nodes {
		nodeTemplate, exists := nodeTemplateMap[node.NodeTemplateID]
		if !exists {
			continue
		}

		// 构建节点进度信息
		nodeProgress := s.buildNodeProgressForExistingNode(nodeTemplate, node, reviewTaskMap[node.ID])
		nodeProgresses = append(nodeProgresses, nodeProgress)

		// 检查是否有未完成的审批任务
		for _, task := range reviewTaskMap[node.ID] {
			if task.Status == 1 { // 状态为1表示审核中
				return nodeProgresses, nil // 找到当前审批节点，返回结果
			}
		}
	}

	return nodeProgresses, nil
}

// buildNodeProgressForExistingNode 为已存在的节点构建详细进度信息
// 该方法专门处理已创建的节点实例，构建包含实际审批任务状态的完整进度信息
//
// 参数说明:
//   - nodeTemplate: 节点对应的模板信息，包含节点的基础配置和审批策略
//   - node: 已创建的节点实例，包含节点的实际状态和时间信息
//   - reviewTasks: 该节点下的所有审批任务列表，可能为空（如节点刚创建）
//
// 返回值:
//   - NodeProgress: 包含节点模板信息、节点实例状态和审批任务详情的完整进度对象
//
// 使用注意事项:
//  1. 该方法仅适用于已创建的节点，node参数不能为空值
//  2. reviewTasks为空时表示节点存在但尚未分配审批任务
//  3. 返回的进度信息中NodeID字段有值，区别于模板节点的进度信息
//  4. 审批任务的转换依赖ToProgressTask方法，确保该方法正确实现
func (s *Clerk) buildNodeProgressForExistingNode(nodeTemplate entity.NodeTemplate, node entity.Node, reviewTasks []NodeReviewTask) NodeProgress {
	// 本方法的核心功能：将节点模板信息与实际节点状态合并，
	// 并转换所有关联的审批任务为统一的进度任务格式

	// 构建基础进度信息，合并模板配置和节点实例的状态数据
	progress := NodeProgress{
		NodeTemplateID:   nodeTemplate.ID,                               // 节点模板标识
		NodeTemplateName: nodeTemplate.Name,                             // 节点模板名称，用于显示
		ApprovalStrategy: string(nodeTemplate.ApprovalStrategy),         // 审批策略（如：全部通过、任一通过等）
		NodeID:           node.ID,                                       // 节点实例标识，区分于模板节点
		Status:           node.Status,                                   // 节点当前状态（如：待审批、已通过、已拒绝等）
		CreatedAt:        node.CreatedAt,                                // 节点创建时间
		UpdatedAt:        node.UpdatedAt,                                // 节点最后更新时间
		ReviewTasks:      make([]NodeProgressTask, 0, len(reviewTasks)), // 预分配审批任务切片
	}

	// 转换所有审批任务为统一的进度任务格式，保持任务的详细状态信息
	for _, task := range reviewTasks {
		progress.ReviewTasks = append(progress.ReviewTasks, task.ToProgressTask())
	}

	return progress
}

func (s *Clerk) SubscribeEvents(ctx context.Context) <-chan Event {
	return s.EventService.subscribe()
}

func (s *Clerk) getWorkflowFromStartWorkFlowRequest(ctx context.Context, startWorkFlowRequest StartWorkFlowRequest, startNodeID string) (result entity.Workflow, err error) {
	if err = utils.StructCopy(ctx, &result, &startWorkFlowRequest); err != nil {
		return result, err
	}

	// 赋予id
	if startWorkFlowRequest.WorkflowID != "" {
		result.ID = startWorkFlowRequest.WorkflowID
	} else {
		uuidV7, err := uuid.NewV7()
		if err != nil {
			return result, err
		}
		result.ID = uuidV7.String()
	}
	// 赋值状态、当前节点id、结论、自定义参数
	result.Status = entity.WorkflowUnderReviewStatus
	result.CurrentNodeID = startNodeID
	result.Conclusion = startWorkFlowRequest.Conclusion
	result.BusinessParams, err = startWorkFlowRequest.BusinessParams.Marshal()
	if err != nil {
		return result, err
	}
	// 注意：ConditionParams现在通过GetConditionParams()方法从FormContent中提取

	return result, err
}

// passNodeHandlerWithEvents 支持事件收集的节点通过处理
func (s *Clerk) passNodeHandlerWithEvents(ctx context.Context, workflow entity.Workflow, node entity.Node, nodeReviewerTask entity.NodeReviewerTask, tx *gorm.DB, txCtx *TxContext) (err error) {
	// 修改node状态为已完成
	node.Pass()
	if err = s.Reference.UpdateNodeTX(ctx, node, tx); err != nil {
		return err
	}

	// 查询下一个审批节点
	nodeTemplate, err := s.Reference.QueryNodeTemplateByID(ctx, node.NodeTemplateID)
	if err != nil {
		return err
	}
	conditionParams, err := workflow.GetConditionParams()
	if err != nil {
		return err
	}
	nextNodeTemplateID, err := s.Reference.FindNextApprovalNodeRecursive(
		ctx,
		nodeTemplate.NextNodeTemplateID,
		conditionParams,
		make(map[string]bool),
		0,
		10,
	)
	if err != nil {
		// 检查是否为条件不匹配错误
		if isConditionNotMet, _ := infrastructure.IsConditionNotMetError(err); isConditionNotMet {
			// 收集条件不匹配事件
			workflowTemplate, err := s.Reference.QueryWorkflowTemplateByID(ctx, workflow.WorkflowTemplateID)
			if err != nil {
				return err
			}
			txCtx.AddEvent(NewConditionNotMetEvent(workflowTemplate.Name, workflow.SponsorID, workflow.BusinessParams))
		}
		return err
	}

	// 判断是否还存在下一个审批节点
	if nextNodeTemplateID == "" {
		// node为最后一个节点，结束审批流
		// 修改workflow状态为已完成
		workflow.Pass(nodeReviewerTask.Comment)
		if err = s.Reference.UpdateWorkflowTX(ctx, workflow, tx); err != nil {
			return err
		}

		// 节点被审批后的处理已移除（原HandlePassedNode方法已废弃）

		// 收集节点通过事件
		txCtx.AddEvent(NewNodePassedEvent(workflow.ID, nodeReviewerTask.NodeID, nodeReviewerTask.ID))

		// 审批流通过后的处理已移除（原HandlePassedWorkflow方法已废弃）

		// 收集工作流通过事件
		txCtx.AddEvent(NewWorkflowPassedEvent(workflow.ID, nodeReviewerTask.NodeID, nodeReviewerTask.ID))

	} else {
		//  如果还有下一个节点

		// 创建新的node
		nextNode := entity.NewUnderReviewNodeWithStrategy(
			nextNodeTemplateID,
			workflow.ID,
			"", // 保留参数以兼容接口，但不再使用
		)
		if err = s.Reference.CreateNodeTX(ctx, nextNode, tx); err != nil {
			return err
		}

		// 修改workflow的节点相关信息
		workflow.CurrentNodeID = nextNode.ID
		if err = s.Reference.UpdateWorkflowTX(ctx, workflow, tx); err != nil {
			return err
		}

		// 本节点被审批后的处理已移除（原HandlePassedNode方法已废弃）

		// 收集节点通过事件
		txCtx.AddEvent(NewNodePassedEvent(workflow.ID, nodeReviewerTask.NodeID, nodeReviewerTask.ID))

		// 创建审批任务
		nodeReviewerTasks, _, err := s.getTargetNodeReviewerTasks(ctx, nextNode.NodeTemplateID, nextNode.ID, workflow)
		if err != nil {
			return err
		}
		if len(nodeReviewerTasks) == 0 {
			return nil
		}
		if err = s.Reference.CreateReviewerTasksTX(ctx, nodeReviewerTasks, tx); err != nil {
			return err
		}

		// 审批任务创建后的处理已移除（原HandleCrearedReviewTasks方法已废弃）

		// 收集审批任务创建事件
		txCtx.AddEvent(NewReviewTasksCreatedEvent(workflow.ID, nextNode.ID, ""))

		// 自动审批
		if err = s.autoPassReviewerTaskWithEvents(ctx, nodeReviewerTask.ReviewerID, nodeReviewerTasks, tx, txCtx); err != nil {
			return err
		}

	}

	return err
}

// rejectNodeHandlerWithEvents 支持事件收集的节点拒绝处理
func (s *Clerk) rejectNodeHandlerWithEvents(ctx context.Context, workflow entity.Workflow, node entity.Node, nodeReviewerTask entity.NodeReviewerTask, tx *gorm.DB, txCtx *TxContext) (err error) {
	// 修改node状态为已驳回
	node.Reject()
	if err = s.Reference.UpdateNodeTX(ctx, node, tx); err != nil {
		return err
	}

	// 修改workflow的状态
	workflow.TempReject(nodeReviewerTask.Comment)
	if err = s.Reference.UpdateWorkflowTX(ctx, workflow, tx); err != nil {
		return err
	}

	// 节点拒绝后的处理已移除（原HandleRejectedNode方法已废弃）

	// 收集节点拒绝事件
	txCtx.AddEvent(NewNodeRejectedEvent(workflow.ID, nodeReviewerTask.NodeID, nodeReviewerTask.ID))

	// 任务被驳回通知已移除（原HandleRejectedWorkflow方法已废弃）

	// 收集工作流拒绝事件
	txCtx.AddEvent(NewWorkflowRejectedEvent(workflow.ID, nodeReviewerTask.NodeID, nodeReviewerTask.ID))
	return nil
}

func (s *Clerk) getTargetNodeReviewerTasks(ctx context.Context, nodeTemplateID, nodeID string, workflow entity.Workflow) (result []entity.NodeReviewerTask, reviewerIDs []string, err error) {
	// 查询审批人信息
	nodeTemplateReviewers, err := s.Reference.QueryNodeTemplateReviewers(ctx, nodeTemplateID)
	if err != nil {
		return result, reviewerIDs, err
	}

	if len(nodeTemplateReviewers) == 0 {
		return result, reviewerIDs, errors.New("no reviewer found")
	}

	// 根据审批人类型决定如何获取审批人ID
	hasRoleKind := false
	directReviewerIDs := []string{}

	// 先检查是否有角色类型的审批人，同时收集直接指定的审批人ID
	if nodeTemplateReviewers[0].Kind != entity.UserKind {
		hasRoleKind = true
	} else {
		// 非角色类型，直接使用ReviewerIDs
		directReviewerIDs = append(directReviewerIDs, nodeTemplateReviewers[0].GetReviewerIDs()...)
	}

	// 如果有角色类型的审批人，则调用Hook获取审批人ID
	if hasRoleKind {
		// 使用hook查询审批人id
		businessParams, err := NewBusinessParams(workflow.BusinessParams)
		if err != nil {
			return result, reviewerIDs, err
		}

		// 只传递角色类型的ReviewerNos给Hook
		roleReviewerNos := []string{}
		for _, reviewer := range nodeTemplateReviewers {
			if reviewer.Kind != entity.UserKind {
				roleReviewerNos = append(roleReviewerNos, reviewer.GetReviewerNos()...)
			}
		}

		hookReviewerIDs, err := s.Hook.GetReviewerIDs(ctx, nodeTemplateReviewers[0].Kind, roleReviewerNos, workflow.FormContent, businessParams)
		if err != nil {
			return result, reviewerIDs, err
		}

		// 合并Hook返回的审批人ID和直接指定的审批人ID
		reviewerIDs = append(hookReviewerIDs, directReviewerIDs...)
	} else {
		// 没有角色类型，直接使用收集到的审批人ID
		reviewerIDs = directReviewerIDs
	}

	// 创建审批任务
	return entity.NewNodeReviewerTasks(nodeID, reviewerIDs), reviewerIDs, err
}

func (s *Clerk) archiveOtherTasksOfNode(ctx context.Context, nodeID string, tx *gorm.DB) (err error) {
	cond := entity.NodeReviewerTask{NodeID: nodeID, Status: entity.TaskUnderReviewStatus}
	nodeReviewerTask := entity.NodeReviewerTask{Status: entity.TaskArchivedStatus}
	return s.Reference.UpdateNodeReviewerTaskByCondTX(ctx, cond, nodeReviewerTask, tx)
}

// autoPassReviewerTask 自动通过审批任务
// 该方法会检查下一级审批人员中是否包含当前用户，如果包含且启用了自动审批，则自动通过该任务
// 同时会根据节点的审批策略（或批/与批）来决定是否触发节点级别的操作
// autoPassReviewerTaskWithEvents 支持事件收集的自动审批任务处理
func (s *Clerk) autoPassReviewerTaskWithEvents(ctx context.Context, currentUserID string, nextNodeReviewerTasks []entity.NodeReviewerTask, tx *gorm.DB, txCtx *TxContext) (err error) {
	// 如果没有下一级审批任务，直接返回
	if len(nextNodeReviewerTasks) == 0 {
		return nil
	}

	// 获取工作流信息
	workflow, err := s.Reference.QueryAndLockWorkflowByCondTX(ctx, QueryWorkflowCond{
		ReviewerTaskID: nextNodeReviewerTasks[0].ID,
	}, tx)
	if err != nil {
		return err
	}

	// 获取工作流模板信息
	workflowTemplate, err := s.Reference.QueryWorkflowTemplateByID(ctx, workflow.WorkflowTemplateID)
	if err != nil {
		return err
	}

	// 创建审批决策器
	decisionMaker := NewApprovalDecisionMaker(s.Reference)

	// 构建决策参数
	decisionParams := DecisionParams{
		CurrentUserID:         currentUserID,
		Workflow:              workflow,
		WorkflowTemplate:      workflowTemplate,
		NextNodeReviewerTasks: nextNodeReviewerTasks,
		Tx:                    tx,
	}

	// 做出自动审批决策
	autoApprovalDecision, err := decisionMaker.MakeAutoApprovalDecision(ctx, decisionParams)
	if err != nil {
		return err
	}

	// 处理需要自动审批的任务
	nodeProcessed := false // 标记节点是否已经被处理过
	for _, autoApprovalTask := range autoApprovalDecision.AutoApprovalTasks {
		// 更新任务状态
		taskToAutoPass := autoApprovalTask.Task
		taskToAutoPass.Pass()
		// 创建自动审批的comment
		taskToAutoPass.Comment, err = s.createAutoApprovalComment(autoApprovalTask.Reason)
		if err != nil {
			return err
		}
		if err = s.Reference.UpdateNodeReviewerTaskTX(ctx, taskToAutoPass, tx); err != nil {
			return err
		}

		fmt.Printf("Auto approval executed: userID=%s, reason=%s\n", taskToAutoPass.ReviewerID, autoApprovalTask.Reason)

		// 如果节点已经被处理过，跳过节点级别的操作
		if nodeProcessed {
			continue
		}

		// 做出节点审批决策
		nodeApprovalDecision, err := decisionMaker.MakeNodeApprovalDecision(ctx, taskToAutoPass, true, tx)
		if err != nil {
			return err
		}

		// 根据决策结果处理节点级别的操作
		if !nodeApprovalDecision.ApprovalResult.ShouldContinue {
			if nodeApprovalDecision.ApprovalResult.ShouldPass {
				// 节点通过
				err = s.passNodeHandlerWithEvents(ctx, workflow, nodeApprovalDecision.Node, taskToAutoPass, tx, txCtx)
			} else {
				// 节点拒绝（理论上自动审批不会触发拒绝，但为了完整性保留此逻辑）
				err = s.rejectNodeHandlerWithEvents(ctx, workflow, nodeApprovalDecision.Node, taskToAutoPass, tx, txCtx)
			}
			if err != nil {
				return err
			}

			// 归档该节点的其他未被审批的任务
			if err = s.archiveOtherTasksOfNode(ctx, taskToAutoPass.NodeID, tx); err != nil {
				return err
			}

			// 标记节点已经被处理过，避免重复处理
			nodeProcessed = true
		}
		// ShouldContinue 情况下不需要额外操作，继续等待其他审批
	}

	return nil
}

// generateNodeTemplateIDs 生成节点模板ID列表
func (s *Clerk) generateNodeTemplateIDs(nodeConfigs []NodeTemplateConfig) ([]string, error) {
	nodeTemplateIDs := make([]string, len(nodeConfigs))
	for i := range nodeConfigs {
		uuidV7, err := uuid.NewV7()
		if err != nil {
			return nil, err
		}
		nodeTemplateIDs[i] = uuidV7.String()
	}
	return nodeTemplateIDs, nil
}

// createNodeTemplatesAndReviewers 创建节点模板和审批者配置
func (s *Clerk) createNodeTemplatesAndReviewers(ctx context.Context, workflowTemplateID string, nodeConfigs []NodeTemplateConfig, nodeTemplateIDs []string, tx *gorm.DB) error {
	// 建立节点名称到节点ID的映射关系，用于处理条件组中的NextNodeTemplateID
	nodeNameToIDMap := make(map[string]string)
	for i, nodeConfig := range nodeConfigs {
		if nodeConfig.NodeTemplateID != "" {
			nodeNameToIDMap[nodeConfig.NodeTemplateID] = nodeTemplateIDs[i]
		}
	}

	var allReviewers []entity.NodeTemplateReviewer

	var nextNodeTemplateID string
	for i, nodeConfig := range nodeConfigs {
		nodeTemplateID := nodeTemplateIDs[i]

		// 确定下一个节点ID - 使用NextNodeTemplateID字段而不是依赖顺序
		if nodeConfig.NextNodeTemplateID != "" {
			// 从映射中获取真实的节点ID
			if realNodeID, exists := nodeNameToIDMap[nodeConfig.NextNodeTemplateID]; exists {
				nextNodeTemplateID = realNodeID
			}
		}

		// 创建节点模板
		nodeTemplate := entity.NewNodeTemplate(nodeTemplateID, nodeConfig.NodeTemplateName, nextNodeTemplateID, nodeConfig.NodeTemplateKind, workflowTemplateID)

		// 设置审批策略
		if nodeConfig.ReviewerConfig.ApprovalStrategy != "" {
			nodeTemplate.ApprovalStrategy = entity.ApprovalStrategy(nodeConfig.ReviewerConfig.ApprovalStrategy)
		}

		// 设置业务参数
		businessParamsStr, err := nodeConfig.BusinessParams.Marshal()
		if err != nil {
			return err
		}
		nodeTemplate.BusinessParams = businessParamsStr

		// 处理条件节点的ConditionRules，将NextNodeTemplateID从字符串占位符映射为真实的节点模板ID
		if nodeConfig.NodeTemplateKind == 2 && len(nodeConfig.ConditionRules) > 0 {
			// 创建entity.ConditionRule类型的条件规则列表
			updatedConditionRules := make([]entity.ConditionRule, len(nodeConfig.ConditionRules))

			// 遍历条件规则，转换类型并更新NextNodeTemplateID
			for j, conditionRule := range nodeConfig.ConditionRules {
				// 获取真实的节点模板ID
				nextNodeID := conditionRule.NextNodeTemplateID
				if realNodeID, exists := nodeNameToIDMap[conditionRule.NextNodeTemplateID]; exists {
					nextNodeID = realNodeID
				}

				// 转换ConditionGroups
				updatedConditionGroups := make([]entity.ConditionGroup, len(conditionRule.ConditionGroups))
				for k, conditionGroup := range conditionRule.ConditionGroups {
					// 转换Expression到ExpressionData
					expressionDataList := make([]entity.ExpressionData, len(conditionGroup.Conditions))
					for l, condition := range conditionGroup.Conditions {
						expressionDataList[l] = entity.ExpressionData{
							Param:    condition.Param,
							Operator: condition.Operator,
							Value:    condition.Value,
							Type:     condition.Kind,
						}
					}

					// 使用NewConditionGroup构造函数创建entity.ConditionGroup
					updatedConditionGroups[k] = entity.NewConditionGroup(
						expressionDataList,
						entity.LogicalOperator(conditionGroup.LogicalOperator),
					)
				}

				// 使用NewConditionRule构造函数创建entity.ConditionRule
				updatedConditionRules[j] = entity.NewConditionRule(
					updatedConditionGroups,
					nextNodeID,
				)
			}

			// 赋值更新后的条件规则
			nodeTemplate.ConditionRules = updatedConditionRules
		}

		if err := s.Reference.CreateNodeTemplateTX(ctx, nodeTemplate, tx); err != nil {
			return err
		}

		// 创建审批者配置
		reviewers, err := s.buildNodeTemplateReviewer(nodeTemplateID, nodeConfig.ReviewerConfig)
		if err != nil {
			return err
		}
		allReviewers = append(allReviewers, reviewers)
	}

	// 批量保存审批者配置
	return s.Reference.CreateNodeTemplateReviewersTX(ctx, allReviewers, tx)
}

// buildNodeTemplateReviewers 构建节点模板审批者配置
func (s *Clerk) buildNodeTemplateReviewer(nodeTemplateID string, reviewerConfig NodeTemplateReviewerConfig) (result entity.NodeTemplateReviewer, err error) {
	uuidV7, err := uuid.NewV7()
	if err != nil {
		return result, err
	}

	// 确保正确设置ReviewerDepartID
	result = entity.NewNodeTemplateReviewer(
		uuidV7.String(),
		reviewerConfig.Kind,
		nodeTemplateID,
		reviewerConfig.GetReviewerNos(), // 将单个 ReviewerNo 转换为切片
		reviewerConfig.GetReviewerIDs(),
	)

	return result, nil
}

// ChangeNodeReviewer 更改节点办理人员
func (s *Clerk) ChangeNodeReviewer(ctx context.Context, req ChangeNodeReviewerRequest) (err error) {
	// 启动事务
	tx, commitFunc := s.beginTx()
	defer func() {
		err = commitFunc(err)
	}()

	// 查询审批任务
	task, err := s.Reference.QueryNodeReviewerTaskByIDTX(ctx, req.TaskID, tx)
	if err != nil {
		return err
	}

	// 校验任务状态
	if !task.IsValidToReview() {
		return errors.New("当前任务状态不支持更改办理人员")
	}

	// 更新审批人员
	task.ReviewerID = req.NewReviewerID
	if err = s.Reference.UpdateNodeReviewerTaskTX(ctx, task, tx); err != nil {
		return err
	}

	return nil
}

// AddNodeReviewer 添加同环节办理人员
func (s *Clerk) AddNodeReviewer(ctx context.Context, req AddNodeReviewerRequest) (err error) {
	// 启动事务
	tx, commitFunc := s.beginTx()
	defer func() {
		err = commitFunc(err)
	}()

	// 查询节点信息
	node, err := s.Reference.QueryNodeByIDTX(ctx, req.NodeID, tx)
	if err != nil {
		return err
	}

	// 校验节点状态
	if !node.IsValidToAddReviewer() {
		return errors.New("当前节点状态不支持添加办理人员")
	}

	// 检查是否已存在该审批人员
	existingTasks, err := s.Reference.QueryNodeReviewerTasksByNodeIDTX(ctx, req.NodeID, tx)
	if err != nil {
		return err
	}

	for _, task := range existingTasks {
		if task.ReviewerID == req.ReviewerID && task.IsValidToReview() {
			return errors.New("该人员已是当前节点的办理人员")
		}
	}

	// 创建新的审批任务
	newTasks := entity.NewNodeReviewerTasks(req.NodeID, []string{req.ReviewerID})
	if err = s.Reference.CreateReviewerTasksTX(ctx, newTasks, tx); err != nil {
		return err
	}

	return nil
}

// createAutoApprovalComment 创建自动审批的JSON格式comment
// 参数:
//   - reason: 自动审批的原因
//
// 返回值:
//   - string: JSON格式的comment字符串
//   - error: 序列化失败时返回错误
func (c *Clerk) createAutoApprovalComment(reason string) (string, error) {
	// 构建包含text字段的comment数据结构
	commentData := map[string]any{
		"text": fmt.Sprintf("系统自动审批通过：%s", reason),
	}

	// 使用sonic序列化为JSON字符串
	commentJSON, err := sonic.MarshalString(commentData)
	if err != nil {
		return "", fmt.Errorf("序列化comment失败: %v", err)
	}

	return commentJSON, nil
}

// GenerateWorkflowID 生成工作流ID
// 为使用者提供一个唯一的工作流ID，使用UUID v7算法生成
// UUID v7基于时间戳，具有更好的排序性能和唯一性保证
//
// 参数说明:
//   - ctx: 上下文对象，用于控制请求生命周期
//
// 返回值:
//   - workflowID: 生成的工作流唯一标识符
//   - err: 生成过程中的错误信息，如UUID生成失败
func (s *Clerk) GenerateWorkflowID(ctx context.Context) (workflowID string, err error) {
	// 使用UUID v7算法生成唯一标识符
	// UUID v7相比其他版本具有更好的时间排序特性
	uuidV7, err := uuid.NewV7()
	if err != nil {
		return "", fmt.Errorf("生成工作流ID失败: %v", err)
	}

	// 返回字符串格式的UUID
	return uuidV7.String(), nil
}

// beginTx 开始一个事务并返回事务对象和提交函数
// 提交函数会根据传入的错误决定是提交还是回滚事务
func (s *Clerk) beginTx() (*gorm.DB, func(error) error) {
	// 如果设置了测试用的事务函数，则使用它
	if s.beginTxFunc != nil {
		return s.beginTxFunc()
	}

	tx := s.Reference.Begin()
	return tx, func(err error) error {
		if p := recover(); p != nil {
			s.Reference.Rollback(tx)
			panic(p) // 重新抛出panic
		} else if err != nil {
			s.Reference.Rollback(tx)
			return err
		} else {
			return s.Reference.Commit(tx)
		}
	}
}

// beginTxWithEvents 开始一个支持事件收集的事务
// 该方法会创建事务上下文来收集事件，并在事务提交成功后发布所有收集的事件
// 如果事务回滚但有错误事件，会在回滚后发布错误事件
//
// 参数说明:
//   - ctx: 上下文对象，用于控制请求生命周期
//
// 返回值:
//   - *gorm.DB: 数据库事务对象
//   - *TxContext: 事务上下文，用于收集事件
//   - func(error) error: 提交函数，根据传入错误决定提交或回滚
func (s *Clerk) beginTxWithEvents(ctx context.Context) (*gorm.DB, *TxContext, func(error) error) {
	// 如果设置了测试用的事务函数，则使用它（但不支持事件收集）
	if s.beginTxFunc != nil {
		tx, commitFunc := s.beginTxFunc()
		txContext := &TxContext{}
		return tx, txContext, commitFunc
	}

	// 创建事务上下文
	txContext := &TxContext{}
	tx := s.Reference.Begin()

	return tx, txContext, func(err error) error {
		if p := recover(); p != nil {
			// 发生panic时回滚事务并清空事件
			s.Reference.Rollback(tx)
			txContext.Clear()
			panic(p) // 重新抛出panic
		} else if err != nil {
			// 发生错误时回滚事务
			s.Reference.Rollback(tx)

			// 发布错误事件
			s.publishEvents(ctx, txContext)
			return err
		} else {
			// 提交事务
			if commitErr := s.Reference.Commit(tx); commitErr != nil {
				txContext.Clear()
				return commitErr
			}

			// 事务提交成功后，发布所有收集的事件
			s.publishEvents(ctx, txContext)
			return nil
		}
	}
}

// publishEvents 发布事务上下文中收集的事件
// 该方法会遍历事务上下文中的所有事件并逐一发布
// 事件发布失败不会影响业务流程，只会记录错误（目前注释掉）
//
// 参数说明:
//   - ctx: 上下文对象，用于控制请求生命周期
//   - txContext: 事务上下文，包含需要发布的事件列表
func (s *Clerk) publishEvents(ctx context.Context, txContext *TxContext) {
	// 获取事件列表并发布
	events := txContext.GetEvents()
	for _, event := range events {
		if publishErr := s.EventService.publish(ctx, event); publishErr != nil {
			// 事件发布失败不影响业务流程，只记录错误
			// logc.Errorf(ctx, "Failed to publish event: %v, error: %v", event, publishErr)
		}
	}
	txContext.Clear()
}

// findFirstBusinessNode 查找第一个业务节点ID
// 根据NodeTemplateKind为3(开始节点)的配置中的NextNodeTemplateID来确定第一个业务节点
func (s *Clerk) findFirstBusinessNode(nodeConfigs []NodeTemplateConfig, nodeTemplateIDs []string) string {
	// 建立NodeTemplateID到实际生成ID的映射
	nodeIDMap := make(map[string]string)
	for i, config := range nodeConfigs {
		if config.NodeTemplateID != "" {
			nodeIDMap[config.NodeTemplateID] = nodeTemplateIDs[i]
		}
	}

	// 查找开始节点类型的配置
	for _, config := range nodeConfigs {
		if config.NodeTemplateKind == entity.NodeTemplateKindStart && config.NextNodeTemplateID != "" {
			// 如果开始节点指定了下一个节点，返回对应的实际ID
			if realID, exists := nodeIDMap[config.NextNodeTemplateID]; exists {
				return realID
			}
		}
	}

	// 如果没有找到开始节点配置或NextNodeTemplateID，返回第一个业务节点ID（兜底逻辑）
	if len(nodeTemplateIDs) > 0 {
		return nodeTemplateIDs[0]
	}

	return ""
}
